<!-- 管理员详情 -->
<!-- 管理员详情 -->
<template>
  <el-dialog
    v-model="dialogVisible"
    :width="dialogWidth"
    :title="`编辑剧集(${dramaTitle})`"
    alignCenter
    draggable
    appendToBody
    destroyOnClose
    lockScroll
    :closeOnClickModal="false"
  >
    <div v-loading="initLoading" style="min-height: 44vh">
      <div class="btns">
        <el-button type="primary" @click="replaceEpisodeCover">一键替换剧集封面</el-button>
      </div>
      <div id="slick-list-box" class="slick-list-box" :style="{ '--img-width': imgwidth, '--img-height': imgHeight }">
        <slick-list v-model:list="dramaEpisodeList" axis="xy" appendTo="#slick-list-box" tag="ul" useDragHandle class="list">
          <div class="list-item" style="align-items: center; justify-content: center; min-height: 110px; cursor: pointer" @click="addVideoRClick()">
            <el-icon size="16px">
              <icon-plus></icon-plus>
            </el-icon>
            <span style="font-size: 14px">添加剧集</span>
          </div>
          <slick-item v-for="(item, index) in dramaEpisodeList" :key="item.episodeId" class="list-item" :index="index" tag="li">
            <div class="left-box">
              <div class="image-box">
                <base-image class="img" :src="item.episodeCover" :previewSrcList="[item.episodeCover!]"></base-image>
              </div>
              <div style="display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between">
                <span>剧集标题: {{ item.episodeTitle || `第${index + 1}集` }}</span>
                <span>第几集: {{ item.episodeSeq }}</span>
                <div style="display: flex; flex-direction: row; align-items: center; justify-content: space-between">
                  <el-button :icon="IconSolarPlayLinear" type="primary" circle title="播放" @click="() => videoViewer(item)"></el-button>
                  <el-button :icon="IconSolarEraserLinear" type="primary" circle title="编辑视频" @click="() => editVideoRClick(item, index)"></el-button>
                  <el-button :icon="IconSolarTrashBinTrashLinear" type="danger" title="删除视频" circle @click="deleteVideoRClick(item.episodeId!)"></el-button>
                </div>
              </div>
            </div>
            <drag-handle class="drag-handle" tag="div">
              <el-icon size="32px">
                <icon-solar-sort-vertical-line-duotone></icon-solar-sort-vertical-line-duotone>
              </el-icon>
            </drag-handle>
          </slick-item>
        </slick-list>
      </div>
    </div>
    <div style="padding-top: 16px">
      <el-button
        :icon="IconSolarSortVerticalLineDuotone"
        :disabled="submitLoading"
        :loading="submitLoading"
        style="width: 100%"
        type="success"
        @click="() => submit()"
      >
        <span>提交排序</span>
        <span class="hide" style="margin-left: 4px; font-size: 12px">(拖拽排序图标可排序)</span>
      </el-button>
    </div>
    <!-- 添加剧集组件 -->
    <add-episode ref="addEpisodeRef"></add-episode>
    <!-- 编辑剧集组件 -->
    <edit-episode ref="editEpisodeRef"></edit-episode>
    <!-- 视频预览组件 -->
    <rest-video-viewer ref="restVideoViewerRef"></rest-video-viewer>
  </el-dialog>
</template>

<script setup lang="ts">
  import IconPlus from '~icons/ep/plus';
  import IconSolarSortVerticalLineDuotone from '~icons/solar/sort-vertical-line-duotone';
  import IconSolarTrashBinTrashLinear from '~icons/solar/trash-bin-trash-linear';
  import IconSolarEraserLinear from '~icons/solar/eraser-linear';
  import IconSolarPlayLinear from '~icons/solar/play-linear';
  import {
    type DramaEpisode,
    batchEditDamaEpisodeAxios,
    delDamaEpisodeAxios,
    getDramaEpisodeListAxios,
    replaceEpisodeCoverAxios,
  } from '@/api/drama-management';
  import EditEpisode from './edit-episode.vue';
  import AddEpisode from './add-episode.vue';
  import { DragHandle, SlickItem, SlickList } from 'vue-slicksort';

  type $ShowData = {
    dramaId: number;
    dramaTitle: string;
  };
  const imgwidth = '45px';
  const imgHeight = '80px';
  const submitLoading = ref(false);

  const addEpisodeRef: $RefComp<typeof AddEpisode> = ref(null);
  const editEpisodeRef: $RefComp<typeof EditEpisode> = ref(null);
  const restVideoViewerRef: $RefComp<'RestVideoViewer'> = ref(null);
  const initLoading = ref(false);
  const dramaEpisodeList = ref<DramaEpisode[]>([]);
  const dramaId = ref(-1);
  const dramaTitle = ref('');
  const dialogVisible = ref(false);
  const dialogWidth = computed(() => (dramaEpisodeList.value.length > 8 ? '80vw' : '50vw'));

  /**
   * 显示
   */
  async function show(data: $ShowData) {
    initLoading.value = true;
    dialogVisible.value = true;
    dramaId.value = data.dramaId;
    dramaTitle.value = data.dramaTitle;
    dramaEpisodeList.value = [];
    try {
      initLoading.value = true;
      const res = await getDramaEpisodeListAxios(dramaId.value);
      dramaEpisodeList.value = res.data;
      initLoading.value = false;
    } catch (error) {
      initLoading.value = false;
    }
  }

  /**
   * 隐藏
   */
  function hide() {
    dialogVisible.value = false;
  }
  /** 预览视频 */
  function videoViewer(item: DramaEpisode) {
    restVideoViewerRef.value?.show({
      src: item.episodeUrl!,
      poster: item.episodeCover,
    });
  }

  /** 删除剧集 */
  function deleteVideoRClick(episodeId: number) {
    ElMessageBox.confirm('删除后不可恢复，您确定删除该集吗？', '温馨提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      draggable: true,
      beforeClose: async (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true;
          try {
            const res = await delDamaEpisodeAxios(episodeId);
            dramaEpisodeList.value = res.data;
            instance.confirmButtonLoading = false;
            done();
            ElToast.success('删除成功');
          } catch (error) {
            instance.confirmButtonLoading = false;
            ElToast.error(error.msg || '删除失败，-BD004');
          }
        } else {
          done();
        }
      },
    });
  }

  /** 点击添加视频 */
  function addVideoRClick() {
    addEpisodeRef.value?.show({
      dramaId: dramaId.value,
      dramaTitle: dramaTitle.value,
      addCallBack(data: DramaEpisode[]) {
        dramaEpisodeList.value.push(...data);
      },
    });
  }

  /** 点击编辑视频 */
  function editVideoRClick(item: DramaEpisode, index: number) {
    editEpisodeRef.value?.show({
      dramaEpisode: item,
      dramaTitle: dramaTitle.value,
      editCallBack(data: DramaEpisode) {
        dramaEpisodeList.value.splice(index, 1, { ...item, ...data });
      },
    });
  }

  /** 提交 */
  async function submit() {
    try {
      submitLoading.value = true;
      const list = dramaEpisodeList.value.map((item) => item.episodeId!);
      const res = await batchEditDamaEpisodeAxios({ episodeList: list, dramaId: dramaId.value });
      dramaEpisodeList.value = res.data;
      submitLoading.value = false;
      ElToast.success('提交成功');
    } catch (error) {
      submitLoading.value = false;
      ElToast.error(error.msg || '提交失败，-BD003');
    }
  }

  const replaceEpisodeCoverLoading = ref(false);
  /** 替换剧集封面 */
  function replaceEpisodeCover() {
    ElMessageBox.confirm('确定将短剧封面替换所有剧集的封面吗?', '温馨提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      draggable: true,
    })
      .then(async () => {
        try {
          replaceEpisodeCoverLoading.value = true;
          await replaceEpisodeCoverAxios(dramaId.value);
          replaceEpisodeCoverLoading.value = false;
          ElToast.success('操作成功');
        } catch (error) {
          replaceEpisodeCoverLoading.value = false;
          ElToast.error(error.msg || '操作失败，-BD003');
        }
      })
      .catch(() => {
        console.log('取消');
      });
  }

  defineExpose({ show, hide });
</script>

<style lang="scss" scoped>
  .btns {
    display: flex;
    justify-content: end;
    margin-bottom: 10px;
  }

  .list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
    grid-gap: 15px;
    width: 100%;
    max-height: 70vh;
    overflow-y: auto;
  }

  .hide {
    color: #322626;
  }

  .list-item {
    box-sizing: border-box;
    display: flex;
    flex-flow: row nowrap;
    align-items: stretch;
    justify-content: space-between;
    padding: 15px;
    padding-right: 0;
    background: var(--el-fill-color);
    border-radius: 4px;

    .left-box {
      display: flex;
      flex-flow: row nowrap;
      align-items: stretch;
      justify-content: space-between;
    }

    .drag-handle {
      display: flex;
      flex-flow: row nowrap;
      align-items: center;
      justify-content: center;
      padding: 15px;
      cursor: grabbing;
    }
  }

  .image-box {
    padding-right: 15px;

    .img {
      width: var(--img-width);
      height: var(--img-height);
      border-radius: 5px;
    }
  }

  .img-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: var(--img-width);
    height: var(--img-height);

    &.hover-aciton {
      position: relative;

      .action-box {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 2;
        box-sizing: border-box;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: var(--img-width);
        height: var(--img-height);
        padding: 10px;
        background: var(--el-overlay-color-lighter);
        opacity: 0;
        transition: all 0.3s;
      }

      &:hover .action-box {
        opacity: 1;
      }
    }

    .add-icon {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: 20px;
      color: var(--el-text-color-disabled);
      background: var(--el-fill-color-light);
    }
  }

  .slick-list-box ::-webkit-scrollbar {
    width: 8px;
  }

  .slick-list-box ::-webkit-scrollbar-thumb {
    background: #e2e2e2;
    border-radius: 8px;
  }
  // 鼠标移入样式
  .slick-list-box ::-webkit-scrollbar-thumb:hover {
    background: #9e9e9e;
  }

  .slick-list-box ::-webkit-scrollbar-track {
    background: var(--el-dialog-bg-color);
    border-radius: 8px;
  }
</style>
